function HandleClient(gui, user, date, options, message) {
  this._gui = gui;
  this._user = user;
  this._date = date;
  this._options = options;
  this._message = message;
  
  this._createElements();
};

HandleClient.prototype._createElements = function() {
  //Preset
  var users = (this._message['u']) ? this._message['u'].data : [];
  for (var i = 0, il = users.length; i < il; i++) {
    var tmp = users[i].account;
    this._gui.staff.appendChild(new Option(tmp));
  }
  this._gui.gender.appendChild(new Option(''));
  var genders = Gender.array();
  for (var i = 0, il = genders.length; i < il; i++) {
    var tmp = genders[i];
    this._gui.gender.appendChild(new Option(tmp));
  }
  this._gui.partnership_status.appendChild(new Option(''));
  var partnerships = Partnership.array();
  for (var i = 0, il = partnerships.length; i < il; i++) {
    var tmp = partnerships[i];
    this._gui.partnership_status.appendChild(new Option(tmp));
  }
  var contracts = PrintType.array();
  for (var i = 0, il = contracts.length; i < il; i++) {
    var tmp = contracts[i];
    this._gui.contract.appendChild(new Option(tmp));
  }
  //Object
  var client = (this._message[0] && this._message[0].data[0]) ? this._message[0].data[0] : pz_client.instance();
  if (!client.id && client.staff == '') {
    client.staff = this._user.account;
  }
  if (!client.id && client.date_birth == 0) {
    client.date_birth = null;
  }
  if (!client.id) {
    client.date_birth = 0;
    client.pass_date_exp = 0;
    client.pass_date_issue = 0;
    client.first_contact_date = 0;
  }
  if (client.id) {
    this._gui.nav.style.display = 'table';
    
    var tr, td;
    tr = this._gui.nav.insertRow(-1);
    td = tr.insertCell(-1);
    td.style.cursor = 'pointer';
    td.style.width = '31px';
    var img = document.createElement('img');
    img.src = 'image/nav/home.png';
    td.onclick = function() { location.href = '?t=clients'; };
    td.appendChild(img);
    
    td.style.padding = '0 0 0 10px';
    td = tr.insertCell(-1);
    td.style.padding = '1px 0 0 0';
    td.style.width = '20px';
    var img = document.createElement('img');
    img.src = 'image/nav/split.png';
    td.appendChild(img);
    
    td = tr.insertCell(-1);
    td.style.cursor = 'pointer';
    td.style.width = '80px';
    td.style.fontWeight = 'bold';
    td.onclick = function() { location.href = '?t=clients'; };
    td.appendChild(document.createTextNode('All Clients'));
    
    td = tr.insertCell(-1);
    td.style.padding = '1px 0 0 0';
    td.style.width = '20px';
    var img = document.createElement('img');
    img.src = 'image/nav/split.png';
    td.appendChild(img);
    
    td = tr.insertCell(-1);
    td.appendChild(document.createTextNode('Client ' + client.name_first + ' ' + client.name_family));
    
    td = tr.insertCell(-1);
    td.style.textAlign = 'right';
    td.style.cursor = 'pointer';
    td.style.padding = '0 5px 0 5px';
    td.style.width = '40px';
    td.style.borderLeft = 'solid 1px #c0c0c0';
    var img = document.createElement('img');
    img.src = 'image/nav/back.png';
    td.onclick = function() { history.back(); };
    td.appendChild(img);
  }
  //Display
  this._gui.name_family.value = client.name_family;
  this._gui.name_first.value = client.name_first;
  this._gui.file_folder_num.value = client.file_folder_num;
  this._gui.date_birth.value = (client.date_birth == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(client.date_birth, false), false);
  this._gui.nationality.value = client.nationality;
  for (var i = 0, il = this._gui.gender.options.length; i < il; i++) {
    var tmp = this._gui.gender.options[i];
    if (tmp.text == client.gender) {
      this._gui.gender.selectedIndex = i;
    }
  }
  for (var i = 0, il = this._gui.partnership_status.options.length; i < il; i++) {
    var tmp = this._gui.partnership_status.options[i];
    if (tmp.text == client.partnership_status) {
      this._gui.partnership_status.selectedIndex = i;
    }
  }
  this._gui.addr1.value = client.addr1;
  this._gui.addr2.value = client.addr2;
  this._gui.addr3.value = client.addr3;
  this._gui.phone1.value = client.phone1;
  this._gui.phone2.value = client.phone2;
  this._gui.phone3.value = client.phone3;
  this._gui.email.value = client.email;
  this._gui.pass_num.value = client.pass_num;
  this._gui.pass_date_exp.value = (client.pass_date_exp == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(client.pass_date_exp, false), false);
  this._gui.pass_date_issue.value = (client.pass_date_issue == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(client.pass_date_issue, false), false);
  this._gui.country_birth.value = client.country_birth;
  this._gui.agent.value = client.agent;
  for (var i = 0, il = this._gui.staff.options.length; i < il; i++) {
    var tmp = this._gui.staff.options[i];
    if (tmp.text == client.staff) {
      this._gui.staff.selectedIndex = i;
    }
  }
  this._gui.first_contact_date.value = (client.first_contact_date == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(client.first_contact_date, false), false);
  this._gui.first_contact_detail.value = client.first_contact_detail;
  //Event
  var _self = this;
  this._gui.name_family.onchange = function() { client.name_family = this.value; };
  this._gui.name_first.onchange = function() { client.name_first = this.value; };
  this._gui.file_folder_num.onchange = function() { client.file_folder_num = this.value; };
  this._gui.date_birth.onchange = function() { client.date_birth = this.value; };
  this._gui.date_birth.onclick = function() { _self._selectDate(this, client.date_birth, function(sd) { client.date_birth = SimpleDate.toStamp(sd, false); }, false); };
  this._gui.nationality.onchange = function() { client.nationality = this.value; };
  this._gui.gender.onchange = function() { client.gender = this.options[this.selectedIndex].text; };
  this._gui.partnership_status.onchange = function() { client.partnership_status = this.options[this.selectedIndex].text; };
  this._gui.addr1.onchange = function() { client.addr1 = this.value; };
  this._gui.addr2.onchange = function() { client.addr2 = this.value; };
  this._gui.addr3.onchange = function() { client.addr3 = this.value; };
  this._gui.phone1.onchange = function() { client.phone1 = this.value; };
  this._gui.phone2.onchange = function() { client.phone2 = this.value; };
  this._gui.phone3.onchange = function() { client.phone3 = this.value; };
  this._gui.email.onchange = function() { client.email = this.value; };
  this._gui.pass_num.onchange = function() { client.pass_num = this.value; };
  this._gui.pass_date_exp.onclick = function() { _self._selectDate.call(_self, this, client.pass_date_exp, function(sd) { client.pass_date_exp = SimpleDate.toStamp(sd); }, false); };
  this._gui.pass_date_issue.onclick = function() { _self._selectDate.call(_self, this, client.pass_date_issue, function(sd) { client.pass_date_issue = SimpleDate.toStamp(sd); }, false); };
  this._gui.country_birth.onchange = function() { client.country_birth = this.value; };
  this._gui.agent.onchange = function() { client.agent = this.value; };
  this._gui.staff.onchange = function() { client.staff = this.options[this.selectedIndex].text; };
  this._gui.first_contact_date.onclick = function() { _self._selectDate.call(_self, this, client.first_contact_date, function(sd) { client.first_contact_date = SimpleDate.toStamp(sd); }, false); };
  this._gui.first_contact_detail.onchange = function() { client.first_contact_detail = this.value; };
  //Submit
  //Notice: pz_client is operated by mysqlcustom.php
  this._gui.save.onclick = function() { if (MClientUtils.verifyClient(client, _self._gui) == true) {
                                          new RequestUtils()._custom('client', JSON.stringify([{ n: 'pz_client', a: [client], r: [] }]), function(result, params) { location.href = '?t=client&i=' + result.id; }, { pos: DOMUtils.findPos(this) });
                                        }
                                      };
  
  //Visas and Schools
  this._id = client.id;
  if (this._id) {
    var img = document.createElement('img');
    img.src = 'image/loading.gif';
    this._gui.more.appendChild(img);
    this._loadData();
    
    
    this._gui.print.disabled = false;
    this._gui.contract.disabled = false;
    this._gui.print.onclick = function() { var w = window.open('?t=' + _self._gui.contract.options[_self._gui.contract.selectedIndex].text + '&i=' + client.id, 'Contract', 'width=910,height=768,scrollbars=1,location=0,menubar=1', true);
                                           w.focus(); };
    
  } else {
    this._visas = [];
    this._schools = [];
    this._updateElements();
  }
};

HandleClient.prototype._loadData = function() {
//  DOMUtils.removeChildElements(this._gui.more);
//  var img = document.createElement('img');
//  img.src = 'image/loading.gif';
//  this._gui.more.appendChild(img);
  
  this._visas = null;
  this._schools = null;
  this._retrieveVisas();
  this._retrieveSchools();
};

HandleClient.prototype._verifyData = function() {
  if (this._visas && this._schools) {
    this._updateElements();
  }
};

HandleClient.prototype._retrieveVisas = function() {
  var _self = this;
  new RequestUtils()._read('pz_visa', null, 'client_id = ' + this._id, null, null, null, null, function(result, params) { _self._visas = result.data;
                                                                                                                          _self._verifyData.call(_self);
                                                                                                                        }, null);
};

HandleClient.prototype._retrieveSchools = function() {
  var _self = this;
  new RequestUtils()._read('pz_school', null, 'client_id = ' + this._id, null, null, null, null, function(result, params) { _self._schools = result.data;
                                                                                                                            _self._verifyData.call(_self);
                                                                                                                          }, null);
};

HandleClient.prototype._updateElements = function() {
  MClientUtils.countIt(new RequestUtils());
  
  var tr, td;
  DOMUtils.removeChildElements(this._gui.more);
  var mode = (this._message['m']) ? this._message['m'] : Constant.CLIENT_MODE_VISA;
  var more = new ClientMore(document, this._gui.more, null, null, this._user, this._date, { mode: mode }, null);
  
  var _self = this;
  if (this._id) {
    more._gui.visa.onclick = function() { _self._message['m'] = Constant.CLIENT_MODE_VISA;
                                          _self._updateElements.call(_self);
                                        };
    more._gui.school.onclick = function() { _self._message['m'] = Constant.CLIENT_MODE_SCHOOL;
                                            _self._updateElements.call(_self);
                                          };
  }

  if ((mode == Constant.CLIENT_MODE_VISA && this._visas.length == 0) || (mode == Constant.CLIENT_MODE_SCHOOL && this._schools.length == 0)) {
    tr = more._gui.content.insertRow(-1);
    td = tr.insertCell(-1);
    td.style.padding = '10px 0 10px 30px';
    td.style.fontWeight = 'bold';
    td.appendChild(document.createTextNode('No Records Found'));
  }
  
  if (!this._id) {
    more._gui.add_visa.disabled = true;
    more._gui.add_school.disabled = true;
  }
  
  more._gui.add_visa.onclick = function() { var p = new ModulePopupBox();
                                            var div = document.createElement('div');
                                            var pos = DOMUtils.findPos(this);
                                            p._open(div, { pos: [pos[0] - 1000, pos[1] - 300], width: 1000, t: 'Visa' });
                                            
                                            div.style.verticalAlign = 'top';
                                            new ModuleVisa(document, div, null, null, _self._user, _self._date, { mode: Constant.VISA_MODE_EXIST_POP, id: _self._id, popupBox: p, callbackFunc: function() { _self._message['m'] = Constant.CLIENT_MODE_VISA; _self._loadData.call(_self); } });
                                          };
  more._gui.add_school.onclick = function() { var p = new ModulePopupBox();
                                              var div = document.createElement('div');
                                              var pos = DOMUtils.findPos(this);
                                              p._open(div, { pos: [pos[0] - 1100, pos[1] - 200], width: 1000, t: 'School' });
                                              
                                              div.style.verticalAlign = 'top';
                                              new ModuleSchool(document, div, null, null, _self._user, _self._date, { id: _self._id, popupBox: p, callbackFunc: function() { _self._message['m'] = Constant.CLIENT_MODE_SCHOOL; _self._loadData.call(_self); } });
                                            };
  
  this._fread = {};
  if (mode == Constant.CLIENT_MODE_VISA) {
    for (var i = 0, il = this._visas.length; i < il; i++) {
      var tmp = this._visas[i];
      tr = more._gui.content.insertRow(-1);
      td = tr.insertCell(-1);
      if (i < this._visas.length - 1) {
        td.style.borderBottom = 'solid 1px #aca899';
      }
      var read = new VisaRead(document, td, null, null, _self._user, _self._date, null);
      read._gui.client_num.appendChild(document.createTextNode(tmp.client_num));
      read._gui.visa_date_expiry_current.appendChild(document.createTextNode((tmp.visa_date_expiry_current == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.visa_date_expiry_current, false), false)));
      read._gui.record_conviction.appendChild(MiscUtils.txt2span(tmp.record_conviction, 2));
      read._gui.record_refuse.appendChild(MiscUtils.txt2span(tmp.record_refuse, 2));
      read._gui.record_process.appendChild(MiscUtils.txt2span(tmp.record_process, 4));
      
      read._gui.visa_appl_num.appendChild(document.createTextNode(tmp.visa_appl_num));
      read._gui.visa_appl_date_submit.appendChild(document.createTextNode((tmp.visa_appl_date_submit == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.visa_appl_date_submit, false), false)));
      read._gui.medical_month.appendChild(document.createTextNode(tmp.medical_month + '/' + tmp.medical_year));
      read._gui.pcc_month.appendChild(document.createTextNode(tmp.pcc_month + '/' + tmp.pcc_year));

      
      read._gui.visa_appl_type.appendChild(document.createTextNode(tmp.visa_appl_type));
      read._gui.visa_date_issue.appendChild(document.createTextNode((tmp.visa_date_issue == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.visa_date_issue, false), false)));
      read._gui.visa_date_expiry_new.appendChild(document.createTextNode((tmp.visa_date_expiry_new == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.visa_date_expiry_new, false), false)));
      
      read._gui.visa_result.appendChild(document.createTextNode(tmp.visa_result));
      read._gui.visa_date_pickup.appendChild(document.createTextNode((tmp.visa_date_pickup == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.visa_date_pickup, false), false)));
      
      read._gui.remv._visa = tmp;
      //Notice: pz_visa is operated by mysqlcustom.php
      read._gui.remv.onclick = function() { r = window.confirm('Are you sure?');
                                            if (r) {
                                              new RequestUtils()._custom('visa', JSON.stringify([{ n: 'pz_visa', a: [], r: [this._visa] }]), function(result, params) { _self._loadData.call(_self); }, { pos: DOMUtils.findPos(this) });
                                            }
                                          };
      read._gui.edit._visa = tmp;
      read._gui.edit.onclick = function() { var p = new ModulePopupBox();
                                            var div = document.createElement('div');
                                            var pos = DOMUtils.findPos(this);
                                            p._open(div, { pos: [pos[0] - 1100, pos[1] - 100], width: 1000, t: 'Visa' });
                                            p._gui.close.onclick = function() { p._close(); _self._loadData.call(_self); };
                                            div.style.verticalAlign = 'top';
                                            new ModuleVisa(document, div, null, null, _self._user, _self._date, { mode: Constant.VISA_MODE_EXIST_POP, object: this._visa, popupBox: p, callbackFunc: function() { _self._loadData.call(_self); } });
                                          };
      
      this._fread[tmp.track_id] = { g: read._gui, count_doc: 0, count_visa: 0 };
    }
    this._files = null;
    this._loadData2();
    
  } else if (mode == Constant.CLIENT_MODE_SCHOOL) {
    for (var i = 0, il = this._schools.length; i < il; i++) {
      var tmp = this._schools[i];
      tr = more._gui.content.insertRow(-1);
      td = tr.insertCell(-1);
      if (i < this._schools.length - 1) {
        td.style.borderBottom = 'solid 1px #aca899';
      }
      var read = new SchoolRead(document, td, null, null, _self._user, _self._date, null);
      read._gui.school_name.appendChild(document.createTextNode(tmp.school_name));
      read._gui.course_name.appendChild(document.createTextNode(tmp.course_name));
      read._gui.course_level.appendChild(document.createTextNode(tmp.course_level));
      read._gui.course_date_start.appendChild(document.createTextNode((tmp.course_date_start == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.course_date_start, false), false)));
      
      read._gui.amount_paid.appendChild(document.createTextNode(tmp.amount_paid));
      read._gui.paper_num.appendChild(document.createTextNode(tmp.paper_num));
      read._gui.english_weeks.appendChild(document.createTextNode(tmp.english_weeks));
      read._gui.other_course_length.appendChild(document.createTextNode(tmp.other_course_length));
      read._gui.next_payment_date.appendChild(document.createTextNode((tmp.next_payment_date == 0) ? '' : SimpleDate.format(SimpleDate.fromStamp(tmp.next_payment_date, false), false)));
      
      read._gui.file_note.appendChild(MiscUtils.txt2span(tmp.file_note, 4));
    
      read._gui.remv._school = tmp;
      read._gui.remv.onclick = function() { r = window.confirm('Are you sure?');
                                            if (r) {
                                              new RequestUtils()._write(JSON.stringify([{ n: 'pz_school', a: [], r: [this._school] }]), function(result, params) { _self._loadData.call(_self); }, { pos: DOMUtils.findPos(this) });
                                            }
                                          };
      read._gui.edit._school = tmp;
      read._gui.edit.onclick = function() { var p = new ModulePopupBox();
                                            var div = document.createElement('div');
                                            var pos = DOMUtils.findPos(this);
                                            p._open(div, { pos: [pos[0] - 1200, pos[1] - 200], width: 1000, t: 'School' });
                                            
                                            div.style.verticalAlign = 'top';
                                            new ModuleSchool(document, div, null, null, _self._user, _self._date, { object: this._school, popupBox: p, callbackFunc: function() { _self._loadData.call(_self); } });
                                          };
    }
  }
};

HandleClient.prototype._loadData2 = function() {
  for (tmp in this._fread) {
    DOMUtils.removeChildElements(this._fread[tmp].g.docs_read);
    DOMUtils.removeChildElements(this._fread[tmp].g.visa_read);
  }
  
  this._retrieveFiles();
};

HandleClient.prototype._verifyData2 = function() {
  if (this._files) {
    this._updateElements2();
  }
};

HandleClient.prototype._retrieveFiles = function() {
  var _self = this;
  new RequestUtils()._read('pz_file', null, 'client_id = \'' + this._id + '\'', null, null, null, null, function(result, params) { _self._files = result.data;
                                                                                                                                   _self._verifyData2.call(_self);
                                                                                                                                 }, null);
};

HandleClient.prototype._updateElements2 = function() {
  for (tmp in this._fread) {
    DOMUtils.removeChildElements(this._fread[tmp].g.docs_read);
    DOMUtils.removeChildElements(this._fread[tmp].g.visa_read);
  }
  
  var tr_doc, td_doc, tr_visa, td_visa, a, img, _self = this;
  for (var i = 0, il = this._files.length; i < il; i++) {
    var tmp = this._files[i];
    var fread = this._fread[tmp.visa_track_id]
    if (!fread) {
      continue;
    }
    
    p = new ModulePopupBoxSimpleTip();
    a = document.createElement('a');
    a.href = '#';
    a._tmp = tmp;
    a.onmouseover = function() { var div = document.createElement('div');
                                 div.appendChild(document.createTextNode(this._tmp.name + ', ' + this._tmp.size / 1000 + 'KB'));
                                 var pos = DOMUtils.findPos(this)
                                 p._open(div, { pos: [pos[0] + 80, pos[1] + 75 ] });
                               };
    a.onmouseout = function() { p._close(); }; 
    a.onclick = function() { window.open('download.php?q=' + JSON.stringify({ i: this._tmp.id }), '_blank');
                             return false;
                           };
    a.appendChild(document.createTextNode(MiscUtils.filename(tmp.name, 9)));
    
    img = document.createElement('img');
    img.src = 'image/delete.png';
    img.style.padding = '0 0 0 5px';
    img.style.cursor = 'pointer';
    img._tmp = tmp;
    img.onclick = function() { new RequestUtils()._custom('delete', JSON.stringify({ files: [this._tmp] }), function(result, params) { _self._loadData.call(_self); }, { pos: DOMUtils.findPos(this) });
                             };
    
    if (tmp.type == Constant.FILE_TYPE_DOC) {
      if ((fread.count_doc % 5) == 0) {
        tr_doc = fread.g.docs_read.insertRow(-1);
      }
      td_doc = tr_doc.insertCell(-1);
      td_doc.appendChild(a);
      td_doc.appendChild(img);
      fread.count_doc++;
    } else if (tmp.type == Constant.FILE_TYPE_VISA) {
      if ((fread.count_visa % 5) == 0) {
        tr_visa = fread.g.visa_read.insertRow(-1);
      }
      td_visa = tr_visa.insertCell(-1);
      td_visa.appendChild(a);
      td_visa.appendChild(img);
      fread.count_visa++;
    }
  }
};

HandleClient.prototype._selectDate = function(display, date, callbackFunc, showTime) {
  var div = document.createElement('div');
  var ds = new DateSelect((date == 0) ? null : SimpleDate.fromStamp(date, false), null, { container: div, showTime: showTime });
  ds._selectFunc = function(sd) { callbackFunc(sd);
                                  if (sd) { 
                                    display.value = SimpleDate.format(sd, showTime);
                                  } else {
                                    display.value = '';
                                  }
                                  popupBox._close();
                                };
  
  var popupBox = new ModulePopupBoxSimple();
  var pos = DOMUtils.findPos(display);
  popupBox._open(div, { pos: [pos[0], pos[1] + 85] });
};

